#pragma once
#include "Core.h"

namespace Gut
{
	struct UniformBufferDesc
	{
		unsigned int dataSize;
		unsigned int usage = GL_DYNAMIC_DRAW;
		unsigned int binding;
		void *data = 0;
		unsigned int offset = 0;
	};

	struct UniformBuffer
	{
		unsigned int UBO;
		bool CreateFromDesc(const UniformBufferDesc &desc)
		{
			glGenBuffers(1, &UBO);
			glBindBuffer(GL_UNIFORM_BUFFER, UBO);
			glBufferData(GL_UNIFORM_BUFFER, desc.dataSize, desc.data, desc.usage);
			glBindBufferBase(GL_UNIFORM_BUFFER, desc.binding, UBO);

			return true;
		}

		template <typename T>
		bool CreateFrom(unsigned int binding)
		{
			UniformBufferDesc desc;
			desc.binding = binding;
			desc.dataSize = sizeof(T);

			return CreateFromDesc(desc);
		}

		void Upload(const void *data, size_t off, size_t len) const;
		void Upload(const void *data, size_t len) const;

		template <typename T>
		void Upload(const T &t) const
		{
			Upload((void *)&t, sizeof(T));
		}

		~UniformBuffer()
		{
			glDeleteBuffers(1, &UBO);
		}
	};

}